// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: tianqiang

#pragma once

#include <rapidjson/document.h>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/maicoin/order_v2/error_code.h"
#include "coin2/exchange/maicoin/symbology/product.h"

namespace coin2::exchange::maicoin::order_v2 {

class MaicoinParser : public base::order::BaseParser {
 public:
  using JsonValue = rapidjson::GenericValue<rapidjson::UTF8<>>;
  using ProductOrderBundle = coin::proto::ProductOrderBundle;
  using ProductOrderElement = coin::proto::ProductOrderElement;

 public:
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& doc) override;

 private:
  void ParseAccountBalance();
  void ParseOpenOrderInfo();
  void ParseHistoryOrderInfo();
  void ParseOrderInfos(std::string func_name);
  void ParseFillOrderInfo();
  void ParseSubmitResponse();
  void ParseCancelResponse();

  void ParseWsOrderInfoList(const JsonDocument& document);
  void ParseWsTradeInfoList(const JsonDocument& document);
  void ParseWsBalanceInfoList(const JsonDocument& document);
  void ParseWsMessage();

  void ParseOrderInfo(ProductOrderElement* order, const JsonValue& data);
  void ParseWsOrderInfo(ProductOrderElement* order, const JsonValue& data);
  void ParseFillInfo(ProductFillElement* fill, const JsonValue& data);
  void ParseWsFillInfo(ProductFillElement* fill, const JsonValue& data);

  int32_t ParseErrorMessage(const std::shared_ptr<AsioHttpContext>& http_context);
  bool ParseRawBalance(const JsonValue& doc, RawBalanceMap* raw_balance_map);

 private:
  bool IsMaicoinSpotErrMessage(const JsonValue& doc);
  int64_t GetProcOrderId(const JsonValue& data);
  int64_t GetWsProcOrderId(const JsonValue& data);
  coin::proto::OrderSide GetOrderSide(const std::string& side);
  coin::proto::OrderSide GetFillOrderSide(const std::string& side);
  coin::proto::OrderType GetOrderType(const std::string& type);
  void SetOrderStatus(ProductOrderElement* order, const std::string& status);

 private:
  bool is_account_balance_initialized_ = false;
};

}  // namespace coin2::exchange::maicoin::order_v2
